#include "fGzip.h"
#include <f32file.h>
#include <e32base.h>
#include <EZGzip.h>
#include <libc\string.h>
#include "ApplicationScheme.h"
#include "fUtility.h"

void GzipUtility::CompressGZipFileL(RFs &aFs, TInt aBufferSize, const TDesC& aFileName)
{
    RFile input;

    HBufC *compressedFile = HBufC::NewLC(aFileName.Length()+3);
    _LIT(KCompressedGZipFileName,"%S.gz");
    compressedFile->Des().Format(KCompressedGZipFileName,&aFileName);

    User::LeaveIfError(input.Open(aFs,aFileName,EFileStream | EFileRead | EFileShareAny));
    CleanupClosePushL(input);

    CEZFileToGZip *fileToGZip = CEZFileToGZip::NewLC(aFs,*compressedFile,input,aBufferSize );

    //_LIT(KCompressingToGZipFile,"Compressing file %S to gzip file %S\n");
    //console->Printf(KCompressingToGZipFile,&aFileName,compressedFile);

    while (fileToGZip->DeflateL())
    {
        // loop here until the gzip file is created
    }

    CleanupStack::PopAndDestroy(3); //fileToGZip, input, compressedFile
}

void GzipUtility::DecompressGZipFileL(RFs &aFs, TInt aBufferSize, const TDesC& aFileName)
{
    TInt err(KErrNone);
    RFile output;

    HBufC *decompressedFile = HBufC::NewLC(aFileName.Length()+1);
    _LIT(KDecompressedGZipFileName,"%S_");
    decompressedFile->Des().Format(KDecompressedGZipFileName,&aFileName);

    err = output.Create(aFs, *decompressedFile,EFileStream | EFileWrite |
        EFileShareExclusive);
    if (err == KErrAlreadyExists)
        User::LeaveIfError(output.Open(aFs, *decompressedFile,EFileStream |
        EFileWrite | EFileShareExclusive));
    else 
        User::LeaveIfError(err);
    CleanupClosePushL(output);

    CEZGZipToFile *gZipToFile = CEZGZipToFile::NewLC(aFs,aFileName,output,aBufferSize);

    //_LIT(KDecompressingFromGZipFile,"Decompressing file %S from gzip file %S\n");
    //console->Printf(KDecompressingFromGZipFile, decompressedFile, &aFileName);

    while (gZipToFile->InflateL())
    {
        // loop here until the gzip file is decompressed
    }

    CleanupStack::PopAndDestroy(3); //gZipToFile, output, decompressedFile
}


GzipUtility::GzipUtility()
{

}

GzipUtility::~GzipUtility()
{

}

int GzipUtility::Uncompress( const unsigned char* buf_in, int len_in, unsigned char** buf_out )
{
    *buf_out = NULL;
    RFs fsSession;
    User::LeaveIfError( fsSession.Connect( ) );
    RFile file;

    _LIT( KCompressFile,   "c:\\data\\compress.gz"  );
    _LIT( KUncompressFile, "c:\\data\\compress.gz_" );

    int returnCode = -1;
    if ( file.Replace( fsSession, KCompressFile, EFileWrite ) == KErrNone )
    {
        TPtr8 fileData( ( unsigned char* ) buf_in, len_in, len_in );
        file.Write( fileData );
        file.Close();

        DecompressGZipFileL( fsSession, 0x8000, KCompressFile );

        if( file.Open(fsSession,KUncompressFile,EFileRead) == KErrNone ) 	
        {
            TInt fileSize = 0;
            file.Size( fileSize );

            unsigned char* lpBuffer = new unsigned char [ fileSize ];
            TPtr8 bufferPtr( lpBuffer, fileSize, fileSize );

            User::LeaveIfError( file.Read( bufferPtr ) );

            file.Close();

            returnCode = fileSize;
            *buf_out = lpBuffer;
        }

        fsSession.Delete( KUncompressFile );

    }

    fsSession.Delete( KCompressFile );
    fsSession.Close();
    return returnCode;
}

int GzipUtility::Compress( const unsigned char* buf_in, int len_in, unsigned char** buf_out )
{
    *buf_out = NULL;
    RFs fsSession;
    User::LeaveIfError( fsSession.Connect( ) );
    RFile file;

    _LIT( KUncompressFile, "c:\\data\\compress.dat" );
    _LIT( KCompressFile,   "c:\\data\\compress.dat.gz"  );

    int returnCode = -1;
    if ( file.Replace( fsSession, KUncompressFile, EFileWrite ) == KErrNone )
    {
        TPtr8 fileData( ( unsigned char* ) buf_in, len_in, len_in );
        file.Write( fileData );
        file.Close();

        CompressGZipFileL( fsSession, 0x8000, KUncompressFile );

        if( file.Open(fsSession,KCompressFile,EFileRead) == KErrNone ) 	
        {
            TInt fileSize = 0;
            file.Size( fileSize );

            unsigned char* lpBuffer = new unsigned char [ fileSize ];
            TPtr8 bufferPtr( lpBuffer, fileSize, fileSize );

            User::LeaveIfError( file.Read( bufferPtr ) );

            file.Close();

            returnCode = fileSize;
            *buf_out = lpBuffer;
        }

        fsSession.Delete( KCompressFile );

    }

    fsSession.Delete( KUncompressFile );
    fsSession.Close();
    return returnCode;
}
